package com.mcppro.aidatabase.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mcppro.aidatabase.dto.DatabaseOperationResult;
import com.mcppro.aidatabase.dto.IntentDto;
import com.mcppro.aidatabase.entity.ChatLog;
import com.mcppro.aidatabase.repository.ChatLogRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 聊天日志服务
 * 
 * @author MCP Pro
 */
@Service
@Slf4j
public class ChatLogService {

    private final ChatLogRepository chatLogRepository;
    private final ObjectMapper objectMapper;

    @Autowired
    public ChatLogService(ChatLogRepository chatLogRepository, ObjectMapper objectMapper) {
        this.chatLogRepository = chatLogRepository;
        this.objectMapper = objectMapper;
    }

    /**
     * 记录聊天交互
     */
    @Async
    public void logChatInteraction(String sessionId, String userQuestion, 
                                         IntentDto.IntentResult intent, 
                                         DatabaseOperationResult dbResult, 
                                         String aiResponse) {
        try {
            ChatLog chatLog = new ChatLog();
            chatLog.setSessionId(sessionId);
            chatLog.setUserQuestion(userQuestion);
            
            // 将意图对象序列化为JSON字符串
            if (intent != null) {
                chatLog.setAiIntent(objectMapper.writeValueAsString(intent));
            }
            
            if (dbResult != null) {
                chatLog.setGeneratedSql(dbResult.getExecutedSql());
                chatLog.setExecutionTimeMs(dbResult.getExecutionTimeMs());
                
                // 将查询结果序列化为JSON字符串
                if (dbResult.getData() != null) {
                    chatLog.setSqlResult(objectMapper.writeValueAsString(dbResult.getData()));
                }
                
                chatLog.setExecutionStatus(dbResult.isSuccess() ? 
                        ChatLog.ExecutionStatus.SUCCESS : 
                        ChatLog.ExecutionStatus.FAILED);
                
                if (!dbResult.isSuccess()) {
                    chatLog.setErrorMessage(dbResult.getErrorMessage());
                }
            } else {
                chatLog.setExecutionStatus(ChatLog.ExecutionStatus.FAILED);
                chatLog.setErrorMessage("数据库操作结果为空");
            }
            
            chatLog.setAiResponse(aiResponse);
            
            ChatLog savedLog = chatLogRepository.save(chatLog);
            log.debug("聊天日志保存成功 - ID: {}, 会话: {}", savedLog.getId(), sessionId);
        } catch (Exception e) {
            log.error("保存聊天日志失败 - 会话: {}", sessionId, e);
        }
    }

    /**
     * 记录错误交互
     */
    @Async
    public void logErrorInteraction(String sessionId, String userQuestion, String errorMessage) {
        try {
            ChatLog chatLog = new ChatLog();
            chatLog.setSessionId(sessionId);
            chatLog.setUserQuestion(userQuestion);
            chatLog.setExecutionStatus(ChatLog.ExecutionStatus.FAILED);
            chatLog.setErrorMessage(errorMessage);
            
            ChatLog savedLog = chatLogRepository.save(chatLog);
            log.debug("错误日志保存成功 - ID: {}, 会话: {}", savedLog.getId(), sessionId);
        } catch (Exception e) {
            log.error("保存错误日志失败 - 会话: {}", sessionId, e);
        }
    }

    /**
     * 根据会话ID获取聊天历史
     */
    public List<ChatLog> getChatHistory(String sessionId) {
        try {
            return chatLogRepository.findBySessionIdOrderByCreatedAtAsc(sessionId);
        } catch (Exception e) {
            log.error("获取聊天历史失败 - 会话: {}", sessionId, e);
            return List.of();
        }
    }

    /**
     * 获取最近的聊天记录
     */
    public List<ChatLog> getRecentChats(int limit) {
        try {
            return chatLogRepository.findRecentChatLogs(Math.min(limit, 100)); // 最多100条
        } catch (Exception e) {
            log.error("获取最近聊天记录失败", e);
            return List.of();
        }
    }

    /**
     * 获取聊天统计信息
     */
    public ChatStatistics getChatStatistics() {
        try {
            List<Object[]> statusCounts = chatLogRepository.countByExecutionStatus();
            Double avgExecutionTime = chatLogRepository.getAverageExecutionTime();
            
            ChatStatistics stats = new ChatStatistics();
            
            for (Object[] statusCount : statusCounts) {
                ChatLog.ExecutionStatus status = (ChatLog.ExecutionStatus) statusCount[0];
                Long count = (Long) statusCount[1];
                
                switch (status) {
                    case SUCCESS -> stats.setSuccessCount(count);
                    case FAILED -> stats.setFailedCount(count);
                    case PARTIAL_SUCCESS -> stats.setPartialSuccessCount(count);
                }
            }
            
            stats.setTotalCount(stats.getSuccessCount() + stats.getFailedCount() + stats.getPartialSuccessCount());
            stats.setAverageExecutionTimeMs(avgExecutionTime != null ? avgExecutionTime.longValue() : 0L);
            
            return stats;
        } catch (Exception e) {
            log.error("获取聊天统计信息失败", e);
            return new ChatStatistics();
        }
    }

    /**
     * 清除会话历史
     */
    @Async
    public void clearSessionHistory(String sessionId) {
        try {
            chatLogRepository.deleteBySessionId(sessionId);
            log.info("会话历史清除成功 - 会话: {}", sessionId);
        } catch (Exception e) {
            log.error("清除会话历史失败 - 会话: {}", sessionId, e);
        }
    }

    /**
     * 聊天统计信息内部类
     */
    public static class ChatStatistics {
        private Long totalCount = 0L;
        private Long successCount = 0L;
        private Long failedCount = 0L;
        private Long partialSuccessCount = 0L;
        private Long averageExecutionTimeMs = 0L;

        // Getters and Setters
        public Long getTotalCount() { return totalCount; }
        public void setTotalCount(Long totalCount) { this.totalCount = totalCount; }
        
        public Long getSuccessCount() { return successCount; }
        public void setSuccessCount(Long successCount) { this.successCount = successCount; }
        
        public Long getFailedCount() { return failedCount; }
        public void setFailedCount(Long failedCount) { this.failedCount = failedCount; }
        
        public Long getPartialSuccessCount() { return partialSuccessCount; }
        public void setPartialSuccessCount(Long partialSuccessCount) { this.partialSuccessCount = partialSuccessCount; }
        
        public Long getAverageExecutionTimeMs() { return averageExecutionTimeMs; }
        public void setAverageExecutionTimeMs(Long averageExecutionTimeMs) { this.averageExecutionTimeMs = averageExecutionTimeMs; }
        
        public double getSuccessRate() {
            return totalCount > 0 ? (double) successCount / totalCount * 100 : 0.0;
        }
    }
}